Account settings
Supacharger provides a managed account details page at /account. It loads the signed-in user's canonical account summary, updates names and the configured username policy, persists the selected language, and optionally manages avatar and header media. Successful updates refresh active account menus immediately.
Configuration
PROFILE_IDENTITY: {
USERNAME: 'optional',
AVATAR: 'optional',
HEADER_IMAGE: 'optional',
},
ACCOUNT_SETTINGS: {
LANGUAGE: true,
CANCEL_ACCOUNT: 'disabled',
PRODUCT_PROFILE_PATH: null,
},
ORGANISATIONS: {
ENABLED: false,
AUTHENTICATION_HANDLE: 'disabled',
CHOOSER_PATH: '/account/organisation',
ROUTE_MODE: 'root-handle',
PROFILE_MEDIA: true,
},
BILLING: {
// Existing Stripe settings…
ACCOUNT_SUBJECTS: {
PERSONAL: true,
ORGANISATION: false,
},
},
The database profile columns remain installed in every display mode. These settings control policy and presentation, not migration selection. Keep cancellation disabled or hidden until the application has an approved deletion, retention, billing, and organisation-ownership-transfer workflow.
Validation and persistence
The browser form shares the field contract, but /api/account/details performs the authoritative Zod parse and authenticated mutation. It writes through the canonical profile and language RPCs and returns safe field errors. Email is displayed as verified Auth identity and is changed on the Security page, not through the profile RPC.
Media uploads use the authenticated process-image-upload Edge Function and private user-avatars storage paths. The new path is persisted before the previous object is deleted. A failed profile mutation cleans up the new upload and leaves the prior media intact.
Product extensions
Account extension starters live in the developer-owned src/supacharger.adapters/account/ directory. The CLI adds a missing starter during an update and never overwrites an existing adapter.
- Add ordered product links in
navigation.ts. - Render additional fields inside the managed
FormProviderinprofile-fields.tsx. - Validate and persist those values at the server boundary in
profile-extension.ts. - Use
PRODUCT_PROFILE_PATHonly for a real product-owned route. - Reserve
details-page.tsxand thepresentation.tspassthrough for an intentional application-owned presentation such as Specdrive's licensed interface. - Use
chrome.tsxfor the outer application frame around managed account content. It may render a top header, application sidebar, footer, or any combination.
Core's starter chrome.tsx uses the example AuthenticatedAppShell, so Korunet shows its signed-in header and footer on /account. The managed AccountSettingsShell still owns the account navigation and form content inside that frame. CLI updates add a missing starter but preserve every existing consumer adapter, preventing product navigation from being overwritten or duplicated.
Managed account markup uses only stable sc-account-* and shared sc-control-* presentation hooks. Put the complete layout, spacing, typography, colours, dimensions, responsive rules, and interaction styling in src/styles/supacharger-account.css. The CLI installs this developer-owned starter when absent and preserves it thereafter, so you can fully restyle the account journey without editing managed JSX. Keep this presentation file unlayered so it can override Tailwind-layer defaults.
Scope shared sc-control-* rules to the account surface roots that use them. Do not define generic control selectors at the root of this unlayered stylesheet, because they would override the application's layered authentication theme.
The extension cannot bypass canonical authentication, username policy, media paths, or server validation. Add non-empty English values for every new field and only empty placeholders to secondary catalogues unless translation is explicitly requested.
Privacy and notification adapters
The managed /account/privacy and /account/notifications routes render boolean options returned by developer-owned privacy.ts and notifications.ts adapters. Each adapter returns a title, plain-text description, availability, and validated option descriptors. The save route authenticates the user, reloads the descriptor, and rejects any missing or unexpected option key before invoking product persistence.
Starter adapters return disabled and throw if mutation is attempted. This produces an explicit unavailable message instead of fake toggles or artificial save delays. To enable a surface, load the user's real values at the server, return availability: 'enabled', validate the product identifiers again inside the update adapter, and enforce ownership through RPC checks, grants, and RLS.
Wakekeeper is the reference product integration: vessel UUIDs become option IDs and its adapter persists public trip-log policy through the product-owned upsert_trip_log_privacy RPC. Those vessel tables and rules do not belong in Core. No current consumer has a notification backend, so notification controls remain disabled.
Billing subjects
BILLING.ACCOUNT_SUBJECTS controls which settings surfaces exist; it is separate from the BILLING_ACCESS entitlement gate. When PERSONAL is enabled, Core owns /account/billing, /account/billing/subscribe, and the POST-only Customer Portal route. The management page uses the full application guard, while acquisition uses the onboarded-user guard so a user can recover missing billing access.
Personal Checkout and Portal operations derive the billing subject from the authenticated user and never accept a browser-supplied billing-account UUID. The managed service validates 1–20 recurring Stripe Prices, positive quantities, and a single currency, then checks billing-manager authority before creating Stripe resources.
Organisation billing uses the same service with an organisation UUID. Enable it only with organisations, and implement src/supacharger.adapters/billing/organisation.ts so the current owner or administrator resolves the application organisation to its billing account. The canonical service performs a second billing-account permission check and filters overview data by subject type and ID. Product catalogues and Specdrive's authorised presentation remain developer-owned.